<?php
namespace Modules\User\Entities;

use Modules\Core\Entities\BaseEntity as Model;

use ThrowException;

use Illuminate\Notifications\Notifiable;
use Modules\Asset\Traits\Assetable;
use Modules\Card\Traits\CardAssetable;
use Modules\Core\Traits\DeviceMarkable;
use Modules\Agent\Entities\InviteRecord;
use Modules\Chip\Entities\ChipAsset;
use Modules\User\Entities\UserGroup;
// use Modules\Message\Traits\Messageable;
// use Modules\Stat\Traits\Statable;
// use Modules\Modules\Traits\Unreadable;

use Setting;
use Asset;

// 用户类
class User extends Model
{
    use Notifiable;
    use Assetable;
    use CardAssetable;
    use DeviceMarkable;
    // use Messageable;
    // use Statable;
    // use Unreadable;

    protected $guarded = [];
    protected $hidden = ['password'];
    protected $table = 'users';
    protected $appends = ['level_text'];

    protected $casts = [
        'invite_base_reward' => 'json',
        'options' => 'json',
        'tags' => 'json',
        'invite_added_reward' => 'json'
    ];

    static public $resourceName = '用户';

    // 搜索
    public function scopeSearch($query, $key)
    {
        return $query->where('name', 'like', '%' . $key . '%')->orWhere('phone', 'like', '%' . $key . '%');
    }

    // vip
    public function scopeVip($query)
    {
        return $query->where('vip_status', 1);
    }

    // 某用户邀请的一级+二级粉丝
    public function scopeInviteBy($query, $user)
    {
        return $query->where('inviter_id', $user->id)->orWhere('indirect_inviter_id', $user->id);
    }

    // 筛选直接邀请
    public function scopeDirectInviteBy($query, $user)
    {
        return $query->where('inviter_id', $user->id);
    }

    // 筛选间接邀请
    public function scopeIndirectInviteBy($query, $user)
    {
        return $query->where('indirect_inviter_id', $user->id);
    }

    // 资产余额筛选
    public function scopeAssetFilter($query, Array $filter)
    {
        $assetType = $filter['key'];
        $compareType = $filter['type'];
        $value = @$filter['value'] ?: 0;

        if ($compareType === '>' && $value === 0) {
            return $query;
        }

        return $query->whereHas('assets', function ($q) use ($assetType, $compareType, $value) {
            return $q->where('type', $assetType)->where('balance', $compareType, $value);
        });
    }

    // 邀请好友数筛选
    public function scopeInviteeTotalFilter($query, Array $filter)
    {
        $compareType = $filter['type'];
        $value = $filter['value'] ?: 0;

        // 大于0时补丁
        if ($compareType === '>' && $value === 0) {
            return $query;
        }

        return $query->has('invitees', $compareType, $value);
    }

    public function scopeType($query, $type) 
    {
        if ($type === 'blocked') {
            return $query->blocked();
        }
        elseif ($type === 'marked') {
            return $query->whereNotNull('marked_at');
        }
        else {
            // 按平台查看
            return $query->platformType($type);
        }
    }

    // 已被拉黑的
    public function scopeBlocked($query)
    {
        return $query->where('status', 2);
    }

    // 签到记录
    public function sign_in_record()
    {
        return $this->hasOne('\Modules\User\Entities\SignInRecord', 'user_id');
    }

    // 微信帐号
    public function wechats()
    {
        return $this->hasMany('\Modules\User\Entities\SocialAccount', 'user_id')->where('type', 'wechat');
    }

    // 个人统计数据
    public function stats()
    {
        return $this->hasOne('\Modules\Stats\Entities\UserStats', 'user_id');
    }

    // 银行卡
    public function bank_cards()
    {
        return $this->hasMany('\Modules\Asset\Entities\BankCard', 'user_id');
    }

    // 头条系帐号
    public function byte_dance_accounts()
    {
        return $this->hasMany('\Modules\User\Entities\SocialAccount', 'user_id')->where('type', 'byte_dance');
    }

    // 支付宝帐号
    public function alipay_accounts()
    {
        return $this->hasMany('\Modules\User\Entities\SocialAccount', 'user_id')->where('type', 'alipay');
    }

    // 快手帐号
    public function kuaishou_accounts()
    {
        return $this->hasMany('\Modules\User\Entities\SocialAccount', 'user_id')->where('type', 'kuaishou');
    }

    // 阿里系帐号
    public function ali_accounts()
    {
        return $this->hasMany('\Modules\User\Entities\SocialAccount', 'user_id')->where('type', 'ali');
    }

    // 收货地址
    public function addresses()
    {
        return $this->hasMany('\Modules\User\Entities\Address', 'user_id');
    }

    // 参与的活动
    // public function activities()
    // {
    //     return $this->belongsToMany('\Modules\Activity\Entities\Activity', 'activity_records');
    // }

    // 优惠券
    public function coupons()
    {
        // return $this->hasMany('\Modules\Coupon\Entities\UserCoupon', 'user_id');
        return $this->hasMany('\Modules\Coupon\Entities\UserCoupon', 'user_id')->whereHas('base_coupon');
    }

    // 订单
    public function orders()
    {
        return $this->hasMany('\Modules\Order\Entities\BaseOrder', 'user_id');
    }

    // 开奖package
    public function packages()
    {
        return $this->hasMany('\Modules\Asset\Entities\Package', 'user_id');
    }

    // 开奖packagesku
    public function package_skus()
    {
        return $this->hasMany('\Modules\Asset\Entities\PackageSku', 'user_id');
    }

    // 佣金
    public function brokerages()
    {
        return $this->hasMany('\Modules\Agent\Entities\Brokerage', 'user_id');
    }

    // 贡献的佣金
    public function give_brokerages()
    {
        return $this->hasMany('\Modules\Agent\Entities\Brokerage', 'order_user_id');
    }

    // 此等级下所有分销员
    public function agent_level()
    {
        return $this->belongsTo('\Modules\Agent\Entities\AgentLevel', 'agent_level_index',  'level');
    }

    // 我邀请的人 (此处仅显示直接邀请的人)
    public function invitees()
    {
        return $this->hasMany('\Modules\User\Entities\User', 'inviter_id');
    }

    // 邀请我的人
    public function inviter()
    {
        return $this->belongsTo('\Modules\User\Entities\User', 'inviter_id');
    }

    // 团队长
    public function root_inviter()
    {
        return $this->belongsTo('\Modules\User\Entities\User', 'root_inviter_id');
    }

    // 购物车里的sku
    public function cart_items()
    {
        return $this->hasMany('\Modules\Cart\Entities\CartItem', 'user_id');
    }

    // 碎片
    public function chip_assets()
    {
        return $this->hasMany('\Modules\Chip\Entities\ChipAsset', 'user_id');
    }

    // 拼团记录
    public function groupon_records()
    {
        return $this->belongsToMany('\Modules\Groupon\Entities\GrouponRecord', 'groupon_members');
    }

    // 筛选来源类型
    // public function scopeClientType($query, $type)
    // {
    //     return $query->where('client_type', 'wechat');
    // }

    // public function getCurrentElf()
    // {
    //     if (!$this->elf_id) {
    //         $first = Elf::first();
    //         $this->elf()->sync([$first->id]);
    //         return $first;
    //     }
    //     else {
    //         return $this->elf()->where('id', $this->elf_id)->first() ?: Elf::first();
    //     }
    // }

    // 更新邀请人数 
    public function updateInviteeCount()
    {
        $this->update([
            'direct_invitees_count' =>  self::directInviteBy($this)->count(),
            'indirect_invitees_count' => self::indirectInviteBy($this)->count()
        ]);
    }

    // vip 编号
    public function createVipNumber()
    {
        $num = 29182019;
        $this->vip_number = strVal($this->id + $num);
        $this->save();
    }

    public function getLevelTextAttribute()
    {
        $map = [
            0 => '普通会员',
            1 => '高级会员'
        ];

        return @$map[$this->level] ?: '未知';
    }

    // 是否已被拉黑
    public function isBlocked()
    {
        return $this->status === 2;
    }

    // 当前是否是VIP
    public function isVip()
    {
        return $this->vip_status === 1;
    }

    // 生成邀请码
    public function generateInviteCode()
    {
        if ($this->invite_code) {
            return false;
        }

        $str = strtoupper(str_random(6));

        while (User::where('invite_code', $str)->first()) {
            $str = strtoupper(str_random(6));
        }

        $this->update([
            'invite_code' => $str
        ]);
    }

    // 使用openid和phone查找用户 
    static public function findWithOptions($options)
    {
        $user = null;

        // 使用options查找
        if (@$options['openid']) {
            $openIdType = $options['openid']['type'];
            $optnid = $options['openid']['value'];

            $typeMap = [
                'wechat' => 'wechats',
                'byte_dance' => 'byte_dance_accounts',
                'ali' => 'ali_accounts'
            ];

            $user = User::whereHas($typeMap[$openIdType], function ($query) use ($openid) {
                return $query->where('unionid', $openid)->orWhere('openid', $openid);
            })->first();
        }

        // 未找到user但是有指定phone, 继续找
        if (!$user && @$options['phone']) {
            $phone = $options['phone'];
            $user  = User::where('phone', $phone)->first();
        }

        // 未找到user但是有指定appleid, 继续找
        if (!$user && @$options['apple_id']) {
            $appleId = $options['apple_id'];
            $user  = User::where('apple_id', $appleId)->first();
        }

        return $user;
    }

    // 使用openid和phone查找用户 
    static public function findWithOpenIdOrPhone($openIdType, $openid, $phone = null)
    {
        $typeMap = [
            'wechat' => 'wechats',
            'byte_dance' => 'byte_dance_accounts',
            'kuaishou' => 'kuaishou_accounts',
            'ali' => 'ali_accounts',
            'alipay' => 'alipay_accounts'
        ];

        $user = User::whereHas($typeMap[$openIdType], function ($query) use ($openid) {
            return $query->where('unionid', $openid)->orWhere('openid', $openid);
        })->first();

        if (!$user && $phone) {
            $user  = User::where('phone', $phone)->first();
        }

        return $user;
    }

    // 根据微信授权信息查找或创建用户
    static public function findOrCreateByWechat($data, $clientName, $openidType, $clientSubType = 'miniapp') 
    {
        $isCreated = false;

        $openId = @$data['openId'] ?: @$data['openid'];
        $unionId = @$data['unionId'] ?: @$data['unionid'];
        $user = self::findWithOpenIdOrPhone('wechat', $unionId ?: $openId, @$data['phone']);

        $isRequirePhone = intVal(@Setting::get('sys_register')['is_require_phone'] ?: 0);
        // $isRequirePhone = 1;


        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone  || @$data['phone']) {
                $user = User::create([
                    'name' => @v($data['nickName'], str_random(8)),
                    'headimg' => @$data['avatarUrl'],
                    'city' => @$data['city'],
                    'phone' => @$data['phone'],
                    'gender' => $data['gender'] === 1 ? '男' : '女',
                    // 'client_type' => 'wechat',
                    // 'client_sub_type' => $clientSubType
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));
                $user->registedListenerSync();
            }
        }
        else {
            // 用户非第一次登陆
            // 这里尝试更新一下头像
            if (@$data['avatarUrl']) {
                $user->update([
                    'headimg' => @$data['avatarUrl']
                ]);
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->wechats()->where($where)->first()) {
                $user->wechats()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    'unionid' => $unionId,
                    'headimgurl' => @$data['avatarUrl'] ?: @$data['headimgurl'],
                    'nickname' => @$data['nickName'] ?: @$data['nickname'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'wechat'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }

    // 使用手机号创建用户
    static public function createWithPhone($phone)
    {
        $user = User::create([
            'phone' => $phone,
            'name' => str_random(10)
        ]);

        // 创建用户的回调
        $user->registedListenerSync();

        return $user;
    }

    // 使用手机号创建用户
    static public function createWithAppleID($app_id)
    {
        $user = User::create([
            'apple_id' => $app_id,
            'name' => '游客登陆'.str_random(6)
        ]);

        // 创建用户的回调
        $user->registedListenerSync();

        return $user;
    }

    // 根据微信授权信息查找或创建用户
    static public function findOrCreateByApp($data) 
    {
        $isCreated = false;

        $openId = @$data['openId'] ?: @$data['openid'];
        $unionId = @$data['unionId'] ?: @$data['unionid'];
        $openidType = 'app';
        $clientName = 'default';
        $user = self::findWithOpenIdOrPhone('wechat', $unionId ?: $openId, @$data['phone']);

        $isRequirePhone = 1;
        // $isRequirePhone = 1;


        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone  || @$data['phone']) {
                $user = User::create([
                    'name' => @$data['nickName'] ?: (@$data['nickname'] ?: str_random(8)),
                    'headimg' => @$data['avatarUrl'] ?: @$data['headimgurl'],
                    'city' => @$data['city'],
                    'phone' => @$data['phone'],
                    'gender' => $data['sex'] === 1 ? '男' : '女',
                    // 'client_type' => 'app',
                    // 'client_sub_type' => ''
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));
                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->wechats()->where($where)->first()) {
                $user->wechats()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    'unionid' => $unionId,
                    'headimgurl' => $data['headimgurl'],
                    'nickname' => $data['nickname'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'wechat'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }

    // 根据微信授权信息查找或创建用户
    static public function findOrCreateByAppleId($data) 
    {
        $isCreated = false;

        $user = self::findWithOptions($data);

        $isRequirePhone = 0;
        // $isRequirePhone = 1;

        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone  || @$data['phone']) {
                $user = User::create([
                    'name' => @$data['name'] ?: (@$data['phone'] ?: str_random(8)),
                    'headimg' => @$data['avatarUrl'] ?: @$data['headimgurl'],
                    'city' => @$data['city'],
                    'phone' => @$data['phone'],
                    'apple_id'  => @$data['apple_id'],
                    'gender' => null,
                    // 'client_type' => 'app',
                    // 'client_sub_type' => ''
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));
                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            // 需要绑定手机号
            if (@$data['apple_id'] && !$user->apple_id) {
                $user->bindAppleId($data['apple_id']);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }

    // 根据支付宝小程序授权信息查找或创建用户
    static public function findOrCreateByAlipay($data, $clientName, $openidType, $clientSubType = 'miniapp') 
    {
        $isCreated = false;

        $openId = @$data['user_id'];
        $unionId = @$data['unionId'];
        $user = self::findWithOpenIdOrPhone('alipay', $unionId ?: $openId, @$data['phone']);

        $isRequirePhone = intVal(@Setting::get('sys_register')['is_require_phone'] ?: 0);
        // $isRequirePhone = 1;

        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone || @$data['phone']) {
                $user = User::create([
                    'name' => @v(@$data['nick_name'], str_random(8)),
                    'headimg' => @$data['avatar'],
                    'phone' => @$data['phone'],
                    'city' => @$data['city'],
                    'gender' => @$data['gender'] === 'm' ? '男' : '女',
                    // 'client_type' => 'byte_dance',
                    // 'client_sub_type' => $clientSubType
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));

                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->alipay_accounts()->where($where)->first()) {
                $user->alipay_accounts()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    'unionid' => $unionId,
                    'headimgurl' => @$data['avatar'],
                    'nickname' => @$data['nick_name'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'alipay'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }


    // 根据快手授权信息查找或创建用户
    static public function findOrCreateByKuaishou($data, $clientName, $openidType, $clientSubType = 'miniapp') 
    {
        $isCreated = false;

        $openId = @$data['openId'];
        $unionId = @$data['unionId'];
        $user = self::findWithOpenIdOrPhone('kuaishou', $unionId ?: $openId, @$data['phone']);

        $isRequirePhone = intVal(@Setting::get('sys_register')['is_require_phone'] ?: 0);
        // $isRequirePhone = 1;

        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone || @$data['phone']) {
                $user = User::create([
                    'name' => @v($data['nickName'], str_random(8)),
                    'headimg' => @$data['avatarUrl'],
                    'phone' => @$data['phone'],
                    'city' => @$data['city'],
                    'gender' => $data['gender'] === 1 ? '男' : '女',
                    // 'client_type' => 'byte_dance',
                    // 'client_sub_type' => $clientSubType
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));

                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->kuaishou_accounts()->where($where)->first()) {
                $user->kuaishou_accounts()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    'unionid' => $unionId,
                    'headimgurl' => $data['avatarUrl'],
                    'nickname' => $data['nickName'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'kuaishou'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }


    // 根据微信授权信息查找或创建用户
    static public function findOrCreateByByteDance($data, $clientName, $openidType, $clientSubType = 'miniapp') 
    {
        $isCreated = false;

        $openId = @$data['openId'];
        $unionId = @$data['unionId'];
        $user = self::findWithOpenIdOrPhone('byte_dance', $unionId ?: $openId, @$data['phone']);

        $isRequirePhone = intVal(@Setting::get('sys_register')['is_require_phone'] ?: 0);
        // $isRequirePhone = 1;

        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone || @$data['phone']) {
                $user = User::create([
                    'name' => @v($data['nickName'], str_random(8)),
                    'headimg' => @$data['avatarUrl'],
                    'phone' => @$data['phone'],
                    'city' => @$data['city'],
                    'gender' => $data['gender'] === 1 ? '男' : '女',
                    // 'client_type' => 'byte_dance',
                    // 'client_sub_type' => $clientSubType
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));

                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->byte_dance_accounts()->where($where)->first()) {
                $user->byte_dance_accounts()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    'unionid' => $unionId,
                    'headimgurl' => $data['avatarUrl'],
                    'nickname' => $data['nickName'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'byte_dance'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }


    // 根据淘宝/天猫小程序授权信息查找或创建用户
    static public function findOrCreateByTaobao($data, $clientName, $openidType, $clientSubType = 'miniapp') 
    {
        $isCreated = false;

        $openId = @$data['openId'] ?: @$data['openid'];
        $user = self::findWithOpenIdOrPhone('ali', $openId, @$data['phone']);

        $isRequirePhone = intVal(@Setting::get('sys_register')['is_require_phone'] ?: 0);
        // $isRequirePhone = 1;


        // 用户不存在，请求注册
        if (!$user) {
            // 没有要求手机号或者有手机号
            if (!$isRequirePhone  || @$data['phone']) {
                $user = User::create([
                    'name' => @$data['name'],
                    'headimg' => @$data['headimg'],
                    'city' => @$data['city'],
                    'phone' => @$data['phone'],
                    // 'gender' => $data['gender'] === 1 ? '男' : '女',
                    // 'client_type' => 'ali',
                    // 'client_sub_type' => $clientSubType
                ]);

                $isCreated = true;
                // dispatch(new \Modules\User\Jobs\ReplaceHeadimg($user));
                $user->registedListenerSync();
            }
        }

        // 查找到或者创建了新用户
        if ($user) {
            $where = [
                'openid' => $openId,
                'openid_type' => $openidType,
                'client_name' => $clientName,
            ];

            if (!$user->ali_accounts()->where($where)->first()) {
                $user->ali_accounts()->create([
                    'uuid' => uniqid(),
                    'openid' => $openId,
                    // 'unionid' => null,
                    'headimgurl' => $data['headimg'],
                    'nickname' => $data['name'],
                    'openid_type' => $openidType,
                    'client_name' => $clientName,
                    'type' => 'ali'
                ]);
            }

            // 需要绑定手机号
            if (@$data['phone'] && !$user->phone) {
                $user->bindPhone($data['phone']);
            }

            if ($isRequirePhone && !$user->phone) {
                $user = null;
            }
        }

        return [$user, $isCreated];
    }

    static public function beforeGetList($options)
    {
        if (isset($options['type'])) {
            $options['scopes']['type'] = $options['type'];
            // $options['where']['status'] = $options['status'];
        }

        return $options;
    }

    // 绑定手机号
    public function bindPhone($phone) {
        $this->update([
            'phone' => $phone
        ]);
    }

    // 绑定appleId
    public function bindAppleId($appleId) {
        $this->update([
            'apple_id' => $appleId
        ]);
    }

    // 注册成功后调用
    public function registedListenerSync()
    {
        // 绑定注册设备
        $this->markDevice();

        // 生成邀请码
        $this->generateInviteCode();

        // 注册送积分
        $registerReward = @Setting::get('sys_score')['register_reward'] ?: 0;
        if ($registerReward) {
            $this->asset('score')->in($registerReward, [
                'description' => '注册赠送'
            ]);
        }
    }

    // 绑定邀请人
    public function bindInviter($inviter, $req)
    {
        // 已绑定邀请人
        // if ($this->inviter_id) {
        //     return false;
        // }

        // 判断邀请人当日邀请数是否超出限制，如果是则直接返回
        $maxInvitePerDay = @Setting::get('sys_invite')['max_invite_per_day'];
        if ($maxInvitePerDay) {
            $todayInviteTotal = self::directInviteBy($inviter)->whereDate('created_at', date('Y-m-d'))->count();
            if ($todayInviteTotal >= $maxInvitePerDay) {
                return false;
            }
        }

        if ($inviter && $inviter->id !== $this->id) {

            // 邀请时所在的活动节点
            $inviteNode = NULL;

            // 邀请节点
            if ($req->input('invite_node')) {
                list($nodeType, $nodeUuid) = explode('-', $req->invite_node);
                $inviteNode = self::getNode($nodeType, [
                    'uuid' => $nodeUuid
                ]);
            }

            $inviteIndex = $inviter->invite_total + 1;
            $this->update([
                'inviter_id' => $inviter->id,
                'indirect_inviter_id' => $inviter->inviter_id,
                'root_inviter_id' => $inviter->root_inviter_id ?: $inviter->id,
                'invited_at' => date('Y-m-d H:i:s'),
                'invite_reward_status' => 2,
                'invite_node_type' => @$inviteNode->activityType,
                'invite_node_id' => @$inviteNode->id,
                'invite_node_uuid' => @$inviteNode->uuid,
            ]);

            $record = InviteRecord::Create([
                'indirect_inviter_id' => $inviter->inviter_id,
                'direct_inviter_id' => $inviter->id,
                'user_id' => $this->id,
                'invite_index' => $inviteIndex,
                'invite_at' => date('Y-m-d H:i:s'),
                'invite_node_type' => @$inviteNode->activityType,
                'invite_node_title' => @$inviteNode->title,
                'invite_node_id' => @$inviteNode->id,
                'invite_node_uuid' => @$inviteNode->uuid,
            ]);

            // 更新所在节点的邀请序号
            $record->updateNodeInviteIndex();

            $inviter->update([
                'invite_total' => $inviteIndex
            ]);

        }
    }


    // 获取某个端类型的openid信息
    public function getOpenid($openidType, $clientName)
    {
        $wechat = $this->wechats()->where('openid_type', $openidType)->where('client_name', $clientName)->first();
        return $wechat ? $wechat->openid : null;
    }

    // 获取支付宝上某个端类型的openid信息
    public function getOpenidAtAlipay($openidType, $clientName = 'default')
    {
        $item = $this->alipay_accounts()->where('openid_type', $openidType)->where('client_name', $clientName)->first();
        return $item ? $item->openid : null;
    }


    // 最后活跃时间
    public function updateActiveAt($time = null)
    {
        $time = $time ?: date('Y-m-d H:i:s');
        $this->last_active_at = $time;
        $this->save();
    }

    // 根据addressId获取地址，没有则返回默认地址
    public function getAddressOrDefault($addressId)
    {
        return $this->getAddress($addressId) ?: $this->addresses()->orderBy('is_default', 'desc')->first();
    }

    public function getAddress($addressId)
    {
        return $this->addresses()->where('id', $addressId ?: 0)->first();
    }

    // 获取签到记录
    public function getSignInRecord()
    {
        if (!$this->sign_in_record) {
            $this->sign_in_record()->create([
                'uuid' => uniqid(),
                'days' => []
            ]);
            $this->refresh();
        }
        return $this->sign_in_record;
    }

    // 获取道具卡数量
    public function getCardTotal()
    {
        return $this->card_assets()->sum('balance');
        // return $this->card_asset('show_box')->balance + $this->card_asset('exclude_box')->balance;
    }

    // 签到
    public function signIn()
    {
        return $this->getSignInRecord()->signIn();
    }

    // 是否是新用户
    public function isNewUser()
    {
        //  暂定注册时间小于1小时为新用户
        return (time() - strtotime($this->created_at)) < 3600;
    }

    // 获取团队长
    public function getAgentLeader()
    {
        if ($this->root_inviter && $this->root_inviter->agent_level_index === 4) {
            return $this->root_inviter;
        }

        return NULL;
    }

    // 是否是直接粉丝 
    public function isDirectInvitee($inviter)
    {
        return $this->inviter_id === $inviter->id;
    }

    // 是否是团队长
    public  function isAgentLeader()
    {
        return $this->agent_level_index === 4;
    }

    // 是否是555 自定义
    public  function isAgentLeaderDIY()
    {
        return $this->agent_level_index === 555;
    }

    // 是否是556 自定义(我全都要)
    public  function isAgentLeaderDIY556()
    {
        return $this->agent_level_index === 556;
    }

    // 检查是否有等级更新
    public function checkAgentLevelUpdate()
    {
        // 检查是否可以等级为vip分销员
        if ($this->agent_level_index === 1) {
            if ($this->isVip()) {
                $this->update([
                    'agent_level_index' => 3
                ]);
            }
        }

        // 检查是否可以从vip分销员降级
        if ($this->agent_level_index === 3) {
            if (!$this->isVip()) {
                $this->update([
                    'agent_level_index' => 1
                ]);
            }
        }
    }

    // 检查碎片资产是否足够
    public function checkChipTotalEnough($chipId, $chipTotal)
    {
        $asset = $this->chip_assets()->where('chip_id', $chipId)->first();
        return $asset && ($asset->balance >= $chipTotal);
    }

    // 个人碎片资产
    public function chipAsset($chipId)
    {
        $asset = $this->chip_assets()->where('chip_id', $chipId)->first();
        if (!$asset) {
            $asset = ChipAsset::create([
                'user_id' => $this->id,
                'chip_id' => $chipId
            ]);
        }
        return $asset;
    }

    // 获取碎片余额
    public function getChipAssetBalance($chipId)
    {
        // \Log::error($this->chip_assets);
        $chip = $this->chip_assets->where('chip_id', $chipId)->first();

        return @$chip->balance ?: 0;
    }

    // 更新我的推广佣金
    public function updateMyBrokerage()
    {
        $this->update([
            'pending_money_brokerage' => $this->brokerages()->status('pending')->sum('money'),
            'pending_score_brokerage' => $this->brokerages()->status('pending')->sum('score'),
            'completed_money_brokerage' => $this->brokerages()->status('completed')->sum('money'),
            'completed_score_brokerage' => $this->brokerages()->status('completed')->sum('score'),
        ]);
    }

    // 更新用户贡献的推广佣金
    public function updateBrokerage()
    {
        // 更新用户累计贡献推广佣金
        if (!$this->inviter) {
            return false;
        }

        $this->update([
            'first_money_brokerage' => $this->give_brokerages()->where('invite_level', 0)->where('status', '<>', 2)->sum('money'),
            'first_score_brokerage' => $this->give_brokerages()->where('invite_level', 0)->where('status', '<>', 2)->sum('score'),
            'second_money_brokerage' => $this->give_brokerages()->where('invite_level', 1)->where('status', '<>', 2)->sum('money'),
            'second_score_brokerage' => $this->give_brokerages()->where('invite_level', 1)->where('status', '<>', 2)->sum('score'),
        ]);
    }

    // 是否包含在某个用户组内
    // group为userGroup实例或其它id
    public function isInUserGroup($group) 
    {
        if (!is_object($group)) {
            $group = UserGroup::where('id', $group)->first();
        }

        return $group && $group->isPassed($this);
    }
}
